package com.ht.module.bus.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ht.abnormal.HtException;
import com.ht.constant.BusConstant;
import com.ht.constant.DicConstants;
import com.ht.constant.RedisConstants;
import com.ht.module.bus.entity.TDistrict;
import com.ht.module.bus.entity.TStation;
import com.ht.module.bus.mapper.TDistrictMapper;
import com.ht.module.bus.mapper.TStationMapper;
import com.ht.module.bus.service.TDistrictService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ht.module.bus.service.TStationService;
import com.ht.module.sys.entity.SysDictItem;
import com.ht.util.CommMethod;
import com.ht.util.Pager;
import com.ht.util.RedisUtil;
import com.ht.util.UserUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 区划表 服务实现类
 * </p>
 *
 * @author hejialun
 * @since 2024-07-29
 */
@Service
public class TDistrictServiceImpl extends ServiceImpl<TDistrictMapper, TDistrict> implements TDistrictService {
    @Resource
    private RedisUtil redisUtil;

    @Resource
    private TStationService stationService;

    @Override
    public List<Tree<String>> findTree(TDistrict en, String TopNodeCode) {
        QueryWrapper<TDistrict> qw = getQW(en);
        List<TDistrict> tDistricts = baseMapper.findList(qw);
        List<TDistrict> all = baseMapper.selectList(null);
        //找到当前级别的父级别
        for (TDistrict row : tDistricts) {
            //设置临时父编码
            row.setParentDistrictCodeTmep(row.getParentDistrictCode());
            TDistrict tDistrict = all.stream().filter(x -> StrUtil.equals(row.getParentDistrictCode(), x.getDistrictCode())).findFirst().orElse(null);
            if (tDistrict != null) {
                row.setParentDistrictName(tDistrict.getParentDistrictName());
            }
            //判断可以展示的数据是否存在父id
            TDistrict ptemp = tDistricts.stream().filter(x -> StrUtil.equals(x.getDistrictCode(), row.getParentDistrictCode())).findFirst().orElse(null);
            if (ptemp == null) {
                //没有父id设置为0，顶级节点
                row.setParentDistrictCodeTmep("0");
            }
        }
        //构建树配置
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("districtCode");
        config.setParentIdKey("parentDistrictCodeTmep");
        //定义转换器
        List<Tree<String>> build = TreeUtil.build(tDistricts, TopNodeCode, config, (node, tree) -> {
            tree.setId(node.getDistrictCode());
            tree.setParentId(node.getParentDistrictCode());
            tree.setName(node.getDistrictName());
            CommMethod.initExtra(node, tree);
        });
        return build;
    }

    @Override
    public void add(TDistrict en) {
        //判断当前区划编码是否存在
        TDistrict tDistrict = baseMapper.selectById(en.getDistrictCode());
        if (BeanUtil.isNotEmpty(tDistrict)) {
            throw new HtException("当前区划编码的区划已经存在！");
        }

        //判断是否生成站点
        if (StrUtil.equals(en.getIsCreateStation(), DicConstants.State.ENABLE)) {
            TStation tStation = new TStation()
                    .setStationName(en.getDistrictName())
                    .setDistrictCode(en.getDistrictCode())
                    .setDescription(en.getDistrictName() + "对应站点");
            CommMethod.beanCreate(tStation);
            stationService.add(tStation);
            en.setStationCode(tStation.getStationCode());
        }
        if (StrUtil.isEmpty(en.getParentDistrictCode())) {
            en.setParentDistrictCode("0");
        }
        baseMapper.insert(en);
        redisUtil.del(RedisConstants.DISTRICT_LIST);
    }

    @Override
    public Pager<TDistrict> findPage(Pager<TDistrict> pager, TDistrict en) {
        return baseMapper.findPage(pager, getQW(en));
    }

    @Override
    public void editById(TDistrict en) {
        if (StrUtil.isEmpty(en.getParentDistrictCode())) {
            en.setParentDistrictCode("0");
        }
        baseMapper.updateById(en);
        redisUtil.del(RedisConstants.DISTRICT_LIST);
    }

    @Override
    public List<Tree<String>> findTreeAuth(TDistrict en) {
        //查询所有区划
        String districtCode = UserUtil.getDistrictCode();
        List<Tree<String>> son = findTree(en, districtCode);

        List<Tree<String>> tree = new ArrayList<>();
        //获取当前区划
        TDistrict tDistrict = baseMapper.selectById(districtCode);
        if (BeanUtil.isNotEmpty(tDistrict)) {
            //构建节点
            Tree<String> node = new Tree<>();
            node.setId(tDistrict.getDistrictCode());
            node.setParentId(tDistrict.getParentDistrictCode());
            node.setName(tDistrict.getDistrictName());
            CommMethod.initExtra(tDistrict, node);
            node.setChildren(son);
            tree.add(node);
        }
        return tree;
    }

    @Override
    public List<TDistrict> findListAuth(TDistrict en) {
        List<Tree<String>> treeAuth = findTreeAuth(en);

        // 用于存储所有节点ID的集合
        List<String> nodeIdList = new ArrayList<>();
        // 遍历树结构，获取每个节点的ID，并存入集合
        for (Tree<String> tree : treeAuth) {
            collectNodeIds(tree, nodeIdList);
        }
        if (nodeIdList.isEmpty()) {
            return new ArrayList<>();
        }

        List<TDistrict> tDistricts = baseMapper.selectBatchIds(nodeIdList);
        return tDistricts;
    }

    @Override
    public List<TDistrict> findAll() {
        //先从redis中获取码表值
        Object json = redisUtil.get(RedisConstants.DISTRICT_LIST);
        if (BeanUtil.isNotEmpty(json)) {
            List<TDistrict> tDistricts = JSON.parseArray(json+"", TDistrict.class);
            if (BeanUtil.isNotEmpty(tDistricts) && !tDistricts.isEmpty()) {
                return tDistricts;
            }
        }
        //查询出来
        List<TDistrict> districts = baseMapper.selectList(
                new QueryWrapper<TDistrict>()
                        .eq("state", DicConstants.State.ENABLE)
        );
        redisUtil.set(RedisConstants.DISTRICT_LIST, JSON.toJSONString(districts));
        return districts;
    }

    @Override
    public List<String> getSonList(String code) {
        List<Tree<String>> son = findTree(new TDistrict(), code);
        ArrayList<String> codes = new ArrayList<>();
        for (Tree<String> tree : son) {
            collectNodeIds(tree, codes);
        }
        return codes;
    }

    @Override
    public void delById(String id) {
        baseMapper.deleteById(id);
        redisUtil.del(RedisConstants.DISTRICT_LIST);
    }


    /**
     * 展开树
     *
     * @param tree：被展开的树
     * @param nodeIdList:接受的树节点集合
     */
    @Override
    public void collectNodeIds(Tree<String> tree, List<String> nodeIdList) {
        // 将当前节点的ID添加到集合中
        nodeIdList.add(tree.getId());

        // 如果有子节点，递归收集子节点的ID
        if (CollUtil.isNotEmpty(tree.getChildren())) {
            for (Tree<String> child : tree.getChildren()) {
                collectNodeIds(child, nodeIdList);
            }
        }
    }

    private QueryWrapper<TDistrict> getQW(TDistrict en) {
        QueryWrapper<TDistrict> qw = new QueryWrapper<>();


        if (StrUtil.isNotEmpty(en.getDistrictName())) {
            qw.like("tab.district_name", en.getDistrictName());
        }

        if (StrUtil.isNotEmpty(en.getDistrictCode())) {
            qw.eq("tab.district_code", en.getDistrictCode());
        }

        if (StrUtil.isNotEmpty(en.getDistrictCode())) {
            qw.eq("tab.district_code", en.getDistrictCode());
        }

        if (ObjectUtil.isNotEmpty(en.getState())) {
            qw.eq("tab.state", en.getState());
        }
        qw.eq("tab.del_flag", BusConstant.DEL_FLAG_N);
        qw.orderByDesc("create_date");
        return qw;
    }

}
